#ifndef WORK_C
#define WORK_C
#include "work.h"
#include "ctrb.h"
#include "sensor.h"
#include "pidctr.h"

static pthread_t work_pid,timer_pid;

static WORK_TYPE work_type;
static float set_temper=0,set_humi=0;
static U64 work_time=0,count_time=0;
static WORK_STATE work_state=STATE_NOT_READY;
static CTRB_STATE ctrb_state;

static void *dev;
static int (*func)(void *device,CALLBACK_MSG msg)=NULL;

static RETURN_ID Work_SendCmd2Ctrb(CTRB_CMD cmd)
{
	return Drv_Ctrb_SendCmd(cmd);
}

static void Do_Work_Function()
{
	int piddata=0;
	switch(work_type){
		case TYPE_DO_COLD:
			piddata=(int)Api_Pidctr_Ctr(Drv_Get_Temper(),set_temper,CTR_COLD);
			Work_SendCmd2Ctrb(CMD_COLD_ON);
			break;
		case TYPE_DO_HOT:
			piddata=(int)Api_Pidctr_Ctr(Drv_Get_Temper(),set_temper,CTR_HOT);
			Work_SendCmd2Ctrb(CMD_HOT_ON);
			break;
		default:
			piddata=50;
			break;
	}
	msleep(piddata);
	Work_SendCmd2Ctrb(CMD_ALL_OFF);
	msleep(100-piddata);
	if(Drv_Get_Humi()>set_humi)
		Work_SendCmd2Ctrb(CMD_HUMI_OFF);
	else
		Work_SendCmd2Ctrb(CMD_HUMI_ON);
}

static void Do_Work_SendMsg(MSG_TYPE t,float v)
{
	if(func){
		CALLBACK_MSG msg;
		if(t==MSG_WORK_STATE)
			work_state=(WORK_TYPE)v;
        msg.type=t;
        msg.value=v;
		func(dev,msg);
	}
}

static void Do_Work_CallBack()
{
	Do_Work_SendMsg(MSG_TEMPER,Drv_Get_Temper());
	Do_Work_SendMsg(MSG_HUMI,Drv_Get_Humi());
	Do_Work_SendMsg(MSG_WORK_TIME,(float)count_time);
}

static void Work_Thread()
{
	while(1){
		if(work_state==STATE_WORKING)
			Do_Work_Function();
		else
			msleep(100);
		Do_Work_CallBack();
	}
}

static void Timer_Thread()
{
	int t=0;
	while(1){
		sleep(10);
		t+=1;
		if(t==6){
			if(work_state==STATE_WORKING){
				count_time+=1;
				if(count_time==work_time)
					Api_Work_Stop();
			}
			t=0;
		}
	}
}

RETURN_ID Api_Work_Init(void *device,int (*callback)(void *device,CALLBACK_MSG msg))
{
	int err;
	func=callback;
	dev=device;
	
	Do_Work_SendMsg(MSG_WORK_INIT_STEP,STEP_SENSOR);
	if(Drv_Sensor_Init()!=(-NO_ERROR))
		return WORK_INIT_FAILED;
	
	Do_Work_SendMsg(MSG_WORK_INIT_STEP,STEP_CTRB);
	if(Drv_Ctrb_Init()!=(-NO_ERROR))
		return -WORK_INIT_FAILED;
	
	Do_Work_SendMsg(MSG_WORK_INIT_STEP,STEP_SYSTEM);
	err=pthread_create(&work_pid,NULL,(void *)Work_Thread,NULL);
	if(err!=0){
		DBGINFO("can't create work_thread %s\n!!",strerror(err));
		return -WORK_INIT_FAILED;
	}
	
	err=pthread_create(&timer_pid,NULL,(void *)Timer_Thread,NULL);
	if(err!=0){
		DBGINFO("can't create timer_thread %s\n!!",strerror(err));
		return -WORK_INIT_FAILED;
	}
	Work_SendCmd2Ctrb(CMD_FAN_OFF);
	Work_SendCmd2Ctrb(CMD_LIGHT1_OFF);
	Work_SendCmd2Ctrb(CMD_LIGHT2_OFF);
	Work_SendCmd2Ctrb(CMD_LIGHT3_OFF);
	Api_Work_Stop();
	Do_Work_SendMsg(MSG_WORK_INIT_STEP,STEP_DONE);
	return -NO_ERROR;
}

RETURN_ID Api_Work_Start(float tar_temper,float tar_humi,U64 time)
{
	Api_Pidctr_Init();
	if(Drv_Get_Temper()>tar_temper)
		work_type=TYPE_DO_COLD;
	else
		work_type=TYPE_DO_HOT;
	set_temper=tar_temper;
	set_humi=tar_humi;
	work_time=time;
	count_time=0;
	Work_SendCmd2Ctrb(CMD_FAN_ON);
	Do_Work_SendMsg(MSG_WORK_STATE,(float)STATE_WORKING);
	return -NO_ERROR;
}

RETURN_ID Api_Work_Stop()
{
	Work_SendCmd2Ctrb(CMD_ALL_OFF);
	Work_SendCmd2Ctrb(CMD_FAN_OFF);
	Work_SendCmd2Ctrb(CMD_HUMI_OFF);
	Do_Work_SendMsg(MSG_WORK_STATE,(float)STATE_READY);
	return -NO_ERROR;
}

RETURN_ID Api_Work_Uninit()
{
	Api_Work_Stop();
	pthread_cancel(work_pid);
	pthread_cancel(timer_pid);
	Drv_Ctrb_Uninit();
	Drv_Sensor_UnInit();
}

static RETURN_ID Api_Work_Finished()
{	
	Do_Work_SendMsg(MSG_WORK_STATE,(float)STATE_FINISHED);
	Work_SendCmd2Ctrb(CMD_ALL_OFF);
	sleep(30);
	Api_Work_Stop();
	return -NO_ERROR;
}

RETURN_ID Api_Work_CtrbCmd_Fan(CMD_CTRB_SWITCH s)
{
	switch(s){
		case CTRB_SWITCH_OFF:
			Work_SendCmd2Ctrb(CMD_FAN_OFF);
			break;
		case CTRB_SWITCH_ON:
			Work_SendCmd2Ctrb(CMD_FAN_ON);
			break;
		default:
			return -CTRB_INVALID_CMD;
	}
	return -NO_ERROR;
}

RETURN_ID Api_Work_CtrbCmd_Humi(CMD_CTRB_SWITCH s)
{
	switch(s){
		case CTRB_SWITCH_OFF:
			Work_SendCmd2Ctrb(CMD_HUMI_OFF);
			break;
		case CTRB_SWITCH_ON:
			Work_SendCmd2Ctrb(CMD_HUMI_ON);
			break;
		default:
			return -CTRB_INVALID_CMD;
	}
	return -NO_ERROR;
}

RETURN_ID Api_Work_CtrbCmd_Light1(CMD_CTRB_SWITCH s)
{
	switch(s){
		case CTRB_SWITCH_OFF:
			Work_SendCmd2Ctrb(CMD_LIGHT1_OFF);
			break;
		case CTRB_SWITCH_ON:
			Work_SendCmd2Ctrb(CMD_LIGHT1_ON);
			break;
		default:
			return -CTRB_INVALID_CMD;
	}
	return -NO_ERROR;
}

RETURN_ID Api_Work_CtrbCmd_Light2(CMD_CTRB_SWITCH s)
{
	switch(s){
		case CTRB_SWITCH_OFF:
			Work_SendCmd2Ctrb(CMD_LIGHT2_OFF);
			break;
		case CTRB_SWITCH_ON:
			Work_SendCmd2Ctrb(CMD_LIGHT2_ON);
			break;
		default:
			return -CTRB_INVALID_CMD;
	}
	return -NO_ERROR;
}

RETURN_ID Api_Work_CtrbCmd_Light3(CMD_CTRB_SWITCH s)
{
	switch(s){
		case CTRB_SWITCH_OFF:
			Work_SendCmd2Ctrb(CMD_LIGHT3_OFF);
			break;
		case CTRB_SWITCH_ON:
			Work_SendCmd2Ctrb(CMD_LIGHT3_ON);
			break;
		default:
			return -CTRB_INVALID_CMD;
	}
	return -NO_ERROR;
}

RETURN_ID Api_Work_CtrbCmd_Core(CMD_CTRB_CORE s)
{
	switch(s){
		case CTRB_CORE_OFF:
			Work_SendCmd2Ctrb(CMD_ALL_OFF);
			break;
		case CTRB_CORE_COLD:
			Work_SendCmd2Ctrb(CMD_COLD_ON);
			break;
		case CTRB_CORE_HOT:
			Work_SendCmd2Ctrb(CMD_HOT_ON);
			break;
		default:
			return -CTRB_INVALID_CMD;
	}
	return -NO_ERROR;
}


WORK_STATE Api_Work_Get_WorkState()
{
	return work_state;
}

CTRB_STATE Api_Work_Get_CtrbState()
{
	return ctrb_state;
}

float Api_Work_Get_Temper()
{
	return Drv_Get_Temper();
}

float Api_Work_Get_Humi()
{
	return Drv_Get_Humi();
}

#endif
